# -*- coding: utf-8 -*-
"""
固定大小分块示例 (Fixed-size Chunking)

固定大小分块的优缺点：

优点：
1. ✅ 实现简单，易于理解和控制
2. ✅ 分块大小均匀，便于管理和处理
3. ✅ 计算效率高，适合大规模文档处理
4. ✅ 内存使用可预测，便于资源规划
5. ✅ 与大多数向量数据库兼容性好

缺点：
1. ❌ 可能切断语义完整性，在句子或段落中间分割
2. ❌ 对长短不一的文档适应性差
3. ❌ 重叠机制可能引入冗余信息
4. ❌ 对复杂文档结构（如表格、代码）处理不佳
5. ❌ 需要手动调优 chunk_size 和 chunk_overlap 参数

适用场景：
• 结构相对规整的文档
• 对处理速度要求较高的场景
• 初步的 RAG 系统原型开发

不适用场景：
• 技术文档、学术论文等结构复杂的内容
• 代码文件、表格数据等特殊格式
• 对语义完整性要求极高的应用
"""

from langchain.docstore.document import Document
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings

# =======================
# 1. 准备文本
# =======================
# 假设我们有一个文本文件 example.txt
with open("RAG_1_data.txt", "r", encoding="utf-8") as f:
    text = f.read()

# =======================
# 2. 固定大小分块
# =======================
# CharacterTextSplitter 是 LangChain 提供的基础文本切分器
# chunk_size: 每个块的字符数
# chunk_overlap: 块之间的重叠字符数（保持上下文连续性）
text_splitter = CharacterTextSplitter(
    separator="\n",  # 按换行符切分，如果没有换行符则按字符数量强行切分
    chunk_size=500,  # 每块 500 字符
    chunk_overlap=50  # 相邻块重叠 50 字符
)

# 将文本切分为多个 chunk
chunks = text_splitter.split_text(text)

# 打印前几个 chunk 看看效果
print("总 chunk 数量:", len(chunks))
for i, chunk in enumerate(chunks[:3]):
    print(f"Chunk {i + 1}:\n{chunk}\n{'-' * 40}")

# =======================
# 3. 将 chunk 转为 Document 对象
# =======================
docs = [Document(page_content=chunk) for chunk in chunks]

# =======================
# 4. 生成向量并存入向量数据库
# =======================
# 使用本地嵌入模型
embeddings = HuggingFaceEmbeddings(model_name="D:/models/BAAIbge-base-zh-v1.5", model_kwargs={'device': 'cpu'})
# 使用 FAISS 创建向量数据库
vector_store = FAISS.from_documents(docs, embeddings)

# =======================
# 5. 检索测试
# =======================
query = "介绍 RAG 的基本概念"
docs_found = vector_store.similarity_search(query, k=2)

print("检索结果:")
for doc in docs_found:
    print(doc.page_content)
    print("-" * 50)
